from django.shortcuts import render
from rest_framework.views import APIView
from QQLoginTool.QQtool import OAuthQQ
from rest_framework.response import Response
from django.conf import settings
from rest_framework import status
from rest_framework_jwt.settings import api_settings
from .utils import generate_save_user_token
from .models import OAuthQQUser
from .serializers import QQAuthUserSerializers
import logging
logger = logging.getLogger('django')


class QQOauthURLView(APIView):
    '''拼接qq登录的网址'''

    def get(self, request):
        # 1.提取前端传入的next参数,记录用户从哪里到用户的登录界面.
        next = request.query_params.get('next') or '/'
        '''当前端没有取到值的时候,就会添加默认值到链接的后面,默认值就是'/'''
        # 2.利用qq登录的SDK
        # QQ_CLIENT_ID = '101514053'
        # QQ_CLIENT_SECRET = '1075e75648566262ea35afa688073012'
        # QQ_REDIRECT_URI = 'http://127.0.0.1:8080/oauth_callback.html'
        # oauth = OAuthQQ(client_id=appid, client_secret=appkey, redirect_uri=回调域名, state=记录来源)
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,state=next)
        # 3.创建qq登录对象
        login_url = oauth.get_qq_url()
        # 4.调用里面的方法,拼接qq登录的链接
        return Response({'login_url':login_url})

class QQAuthUserView(APIView):
    def get(self,request):
        #1.获取前端传过来的code
        code = request.query_params.get('code')
        if not code:
            return Response({'message':'缺少code'})
        #2.创建qq登录对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)
        try:
            #3.调用里面的get_access_token()方法想服务器获取access_token
            access_token = oauth.get_access_token(code)
            #调用qq登录对象里面的获取open_id的方法,
            open_id = oauth.get_open_id(access_token)
        except Exception as e:
            #如果程序里面有报错就捕获错误,并且打印到控制终端
            logger.info(e)
            #返回响应的信息
            return Response({'message': 'QQ服务器不可用'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)
        try:
            #在这里如果openid没有绑定用户,就把openid加密之后传给前端,让前端帮忙暂时存储一会
            authQQUserModel = OAuthQQUser.objects.get(open_id=open_id)
        except OAuthQQUser.DoesNotExist:
            access_token_openid = generate_save_user_token(open_id)
            return Response({'access_token':access_token_openid})
        else:
            #如果知道某个模型的对象,并且该模型中有对用的外键这时就可以通过外键获得和其相关联的模型对象
            user = authQQUserModel.user
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 引用jwt中的叫jwt_payload_handler函数(生成payload)
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 函数引用 生成jwt

            payload = jwt_payload_handler(user)  # 根据user生成用户相关的载荷
            token = jwt_encode_handler(payload)  # 传入载荷生成完整的jwt

        return Response({
            'token':token,
            'username':user.username,
            'user_id':user.id
        })

    def post(self,request):
        '''openid绑定用户的接口'''
        #请求前端穿过来的数据
        data = request.data
        #1.0创建序列化器进行反序列化
        serializers = QQAuthUserSerializers(data=data)
        serializers.is_valid(raise_exception=True)
        #2.0调用is_vaild()进行校验
        pass